package pl.edu.agh.neuraleconomy.core.ta.indicator;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import pl.edu.agh.neuraleconomy.core.nn.CoreUtils;
import pl.edu.agh.neuraleconomy.model.exchange.Exchange;

public class ROCCalculator implements ICalculator {
	@SuppressWarnings("unused")
	private Logger logger = Logger.getLogger(getClass());
	private int period;

	public ROCCalculator(int period) {
		this.period = period;
	}

	public Map<Date, Double> calculate(List<Exchange> exchanges) {	
		double [] roc = calculate(CoreUtils.toDoubleArray(exchanges));

		Map<Date, Double> result = new HashMap<Date, Double>();	
		
		int head = getHeadValue();
		int i = 0;
		for (; head < exchanges.size(); i++, head++) {
			Exchange headElem = exchanges.get(head);
			result.put(headElem.getDate(), roc[i]);
		}
		return result;
	}
	
	protected int getHeadValue(){
		return period;
	}

	private Double calculateRoc(Double headValue, Double tailValue) {
		if (tailValue == 0) {
			return Double.MAX_VALUE;
		}

		return (headValue - tailValue) / (tailValue);
	}

	private void validate(double [] data) {
		if (data == null || data.length <= getHeadValue()) {
			throw new IllegalArgumentException("Null object or list to short. Should have at least " + (getHeadValue()+1) + " elements.");
		}
	}

	public double[] calculate(double[] data) {
		validate(data);
		double[] res = new double[data.length - period];

		int head = period;
		int tail = 0;
		for (; head < data.length; tail++, head++) {
			double headElem = data[head];
			double tailElem = data[tail];
			double roc = calculateRoc(headElem, tailElem);

			res[tail] = roc;
		}

		return res;
	}

	public int getInputLenForOutputLen(int outputLen) {
		
		return outputLen + period;
	}

}
